/**
 * 
 */
package com.dalonedrow.module.chivalrysorcery.systems;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.dalonedrow.engine.sprite.base.FontProperties;
import com.dalonedrow.engine.sprite.base.SimpleColor;
import com.dalonedrow.engine.sprite.impl.SoftwareCursor;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.engine.systems.Time;
import com.dalonedrow.engine.systems.base.GameState;
import com.dalonedrow.engine.systems.base.Interactive;
import com.dalonedrow.engine.systems.base.Interface;
import com.dalonedrow.engine.systems.base.ProjectConstants;
import com.dalonedrow.engine.ui.base.border.BorderFactory;
import com.dalonedrow.engine.ui.base.border.GuiBorder;
import com.dalonedrow.globalvariables.constants.hq.GlobalConstants;
import com.dalonedrow.module.hq.rpg.HQInteractiveObject;
import com.dalonedrow.module.hq.ui.views.CharacterChooserView;
import com.dalonedrow.module.hq.ui.views.DungeonScreenView;
import com.dalonedrow.module.hq.ui.views.DungeonSplashView;
import com.dalonedrow.module.hq.ui.views.IntroView;
import com.dalonedrow.module.hq.ui.views.LoadingView;
import com.dalonedrow.module.hq.ui.views.ScratchView;
import com.dalonedrow.pooled.PooledStringBuilder;
import com.dalonedrow.pooled.StringBuilderPool;
import com.dalonedrow.utils.AnimationsLoader;
import com.dalonedrow.utils.TextLoader;
import com.dalonedrow.utils.TextureLoader;
import com.dalonedrow.utils.Watchable;
import com.dalonedrow.utils.Watcher;

/**
 * @author Donald
 */
public final class ChivalryController extends ProjectConstants<HQInteractiveObject>
		implements Watcher {
	/**
	 * {@inheritDoc}
	 */
	@Override
	public GuiBorder getTooltipBorder() throws Exception {
		// TODO Auto-generated method stub
		return BorderFactory.getInstance().getBorderEdgeOf8ImagesBackgroundOf1Color(
				new int[] { 9, 9, 9, 9}, 
				new String[] {
				"tooltip_bl",
				"tooltip_b",
				"tooltip_br",
				"tooltip_l", "tooltip_r",
				"tooltip_tl",
				"tooltip_t",
				"tooltip_tr"
				}, 
				new float[] {GlobalConstants.COL_DB_DARK4[0], GlobalConstants.COL_DB_DARK4[1], GlobalConstants.COL_DB_DARK4[2], 0.85f }, 8, 8);
	}
	/** the Attack cursor. */
	private Pixmap	crsrAttack;
	/** the Default cursor. */
	private Pixmap	crsrDefault;
	/** the Panning East cursor. */
	private Pixmap	crsrE;
	/** the Hand cursor. */
	private Pixmap	crsrHand;
	/** the Move cursor. */
	private Pixmap	crsrMove;
	/** the Panning North cursor. */
	private Pixmap	crsrN;
	/** the Panning North-East cursor. */
	private Pixmap	crsrNE;
	/** the Panning North-West cursor. */
	private Pixmap	crsrNW;
	/** the Panning South cursor. */
	private Pixmap	crsrS;
	/** the Panning South-East cursor. */
	private Pixmap	crsrSE;
	/** the Panning South-West cursor. */
	private Pixmap	crsrSW;
	/** the Panning West cursor. */
	private Pixmap	crsrW;
	/** the Wait cursor. */
	private Pixmap	crsrWait;
	/** the current cursor type displayed. */
	private int		cursor;
	/** flag indicating the project has been initialized. */
	private boolean	initialized	= false;
	/** the reference id of the chosen pc. */
	private int		pc;
	/** Hidden constructor. */
	public ChivalryController() {
		super.setInstance(this);
		GameState.getInstance().addWatcher(this);
		new ChivSorcInteractive();
		pc = -1;
		initialize();
		Time.getInstance().init();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void assignViews() {
		System.out.println("assignv");
		Interface.getInstance().setView(GlobalConstants.VIEW_00_INTRO,
				new IntroView());
		//new ScratchView());
		Interface.getInstance().setView(GlobalConstants.VIEW_01_LOADING,
				LoadingView.getInstance());
		Interface.getInstance().setView(
				GlobalConstants.VIEW_02_CHARACTER_CHOOSER,
				CharacterChooserView.getInstance());
		Interface.getInstance().setView(
				GlobalConstants.VIEW_03_DUNGEON_SPLASH,
				DungeonSplashView.getInstance());
		Interface.getInstance().setView(
				GlobalConstants.VIEW_04_DUNGEON_SCREEN,
				DungeonScreenView.getInstance());
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleColor getDefaultFontColor() {
		return GlobalConstants.HQ_MONO_FONT_COLOR;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getFontH1() {
		return "fairlight_12";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getFontH2() {
		return "fairlight_10";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getFontNormal() {
		return "fairlight_12";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getFontTitle() {
		return "fairlight_14";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleColor getInactiveFontColor() {
		return GlobalConstants.HQ_MONO_INACTIVE_COLOR;
	}
	@Override
	public String getMapFilePath() {
		return "data/maps";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getNumGameFonts() {
		final int six = 6;
		return six;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getPcId() {
		return pc;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public HQInteractiveObject getPCObject() {
		HQInteractiveObject io = null;
		try {
			io = (HQInteractiveObject) Interactive.getInstance().getIO(pc);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		return io;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getScrollBarDownArrowImage() {
		return "scroll_down";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getScrollBarUpArrowImage() {
		return "scroll_up";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String getTooltipBorderClass() {
		return "com.dalonedrow.module.hq.ui.borders.HQMonoTooltipBorder";
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleColor getTooltipFontColor() {
		return GlobalConstants.HQ_MONO_FONT_COLOR;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String[] getVXStyleDialogBorderImages() {
		return GlobalConstants.HQ_MONO_VX_BORDER;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float[] getVXStyleDialogGradientBottom() {
		return GlobalConstants.COL_HQ_MONO_VX_DLG_BOTTOM;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float[] getVXStyleDialogGradientTop() {
		return GlobalConstants.COL_HQ_MONO_VX_DLG_TOP;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int[] getVXStyleDialogInsets() {
		final int seven = 7;
		return new int[] { seven, seven, seven, seven };
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getVXStyleDialogXOffset() {
		return 1;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getVXStyleDialogYOffset() {
		return 1;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String[] getVXStyleSpeechBorderImages() {
		return getVXStyleDialogBorderImages();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float[] getVXStyleSpeechGradientBottom() {
		return GlobalConstants.COL_HQ_MONO_VX_SPEECH_BOTTOM;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public float[] getVXStyleSpeechGradientTop() {
		return GlobalConstants.COL_HQ_MONO_VX_SPEECH_TOP;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int[] getVXStyleSpeechInsets() {
		return getVXStyleDialogInsets();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getVXStyleSpeechXOffset() {
		return 1;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getVXStyleSpeechYOffset() {
		return 1;
	}
	/** Initializes the animations library. */
	@Override
	public final void initAnimations() {
		try {
			AnimationsLoader.getInstance("animations.txt", "data");
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initCursors() {
		try {
			crsrDefault = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_default.png"));
			crsrHand = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_hand.png"));
			crsrWait = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_wait.png"));
			crsrE = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_east.png"));
			crsrNE = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_north_east.png"));
			crsrNW = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_north_west.png"));
			crsrN = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_north.png"));
			crsrSE = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_south_east.png"));
			crsrSW = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_south_west.png"));
			crsrS = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_south.png"));
			crsrW = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_west.png"));
			SoftwareCursor.getInstance();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initGameData() {
		try {
			initCursors();
			initGameMaps();
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	@Override
	public void initGameMaps() throws Exception {
		PooledStringBuilder sb0 =
				StringBuilderPool.getInstance().getStringBuilder();
		PooledStringBuilder sb1 =
				StringBuilderPool.getInstance().getStringBuilder();
		for (int i = 0; i < 1; i++) {
			sb0.append("maze_");
			sb1.append("map");
			if (i < 10) {
				sb0.append("0");
			}
			sb0.append(i);
			sb0.append(".xml");
			sb1.append(i);
			ChivSorcScript.getInstance().setGlobalVariable(
					sb1.toString(), sb0.toString());
			sb0.setLength(0);
			sb1.setLength(0);
		}
		sb0.returnToPool();
		sb1.returnToPool();
	}
	@Override
	protected void initialize() {
		try {
			/*
			 * Applet a = GameApplet.getInstance();
			 * a.setFocusTraversalKeysEnabled(false);
			 * a.setFocusTraversalKeysEnabled(false); a.setPreferredSize(new
			 * Dimension( GlobalConsts.SCREEN_WIDTH, GlobalConsts.SCREEN_HEIGHT
			 * )); a.setMinimumSize(new Dimension( GlobalConsts.SCREEN_WIDTH,
			 * GlobalConsts.SCREEN_HEIGHT )); // * enable double buffering //
			 * GLCapabilities capabilities = new GLCapabilities(null);
			 * GLCapabilities capabilities = new
			 * GLCapabilities(GLProfile.getDefault());
			 * capabilities.setDoubleBuffered(true); canvas = new GameCanvas(
			 * capabilities, GlobalConsts.SCREEN_WIDTH,
			 * GlobalConsts.SCREEN_HEIGHT ); a.add(canvas); a.setVisible(true);
			 */
			// assignViews();
			FontProperties.getInstance("data/fonts");
			FontProperties.getInstance().initFontProperties(
					"lovecraft_24.properties");
			FontProperties.getInstance().initFontProperties(
					"thalia_24.properties");
			FontProperties.getInstance().initFontProperties(
					"quentin_20.properties");
			FontProperties.getInstance().initFontProperties(
					"stormbringer_21.properties");
			initTextureLibrary();
			initAnimations();
			initCursors();
			initGameMaps();
			assignViews();
			initialized = true;
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void initTextureLibrary() {
		try {
			TextureLoader.getInstance("data/images", "images.txt");
			TextLoader.getInstance("data/text");
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		initCursors();
	}
	/**
	 * Determines if it is the player's turn.
	 * @return true if it is the player's turn; false otherwise
	 */
	@Override
	public boolean isPlayersTurn() {
		boolean is = false;
		try {
			int ioid =
					ChivSorcScript.getInstance().getGlobalIntVariableValue(
							"ioTurn");
			is = ioid == pc;
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		return is;
	}
	/**
	 * Loads the character chooser screen.
	 * @throws Exception if an error occurs
	 */
	public void loadCharChooser() throws Exception {
		// load screen should switch to HQ CHAR CHOOSER
		LoadingView.getInstance().setNextState(
				GameState.STATE_14HQ_CHAR_CHOOSER);
		LoadingView.getInstance().setLoadAction(
				CharacterChooserView.getInstance(),
				CharacterChooserView.getInstance().getClass().getMethod(
						"init"), new Object[] {});
		LoadingView.getInstance().setRendered(false);
		// game state goes to load screen
		GameState.getInstance().setCurrentState(
				GameState.STATE_11LOADING);
		startGame();
	}
	/**
	 * Loads the character chooser screen.
	 * @throws Exception if an error occurs
	 */
	public void loadDungeonScreen() throws Exception {
		// load screen should switch to HQ CHAR CHOOSER
		LoadingView.getInstance().setNextState(
				GameState.STATE_16HQ_DUNGEON_SCREEN);
		LoadingView.getInstance().setLoadAction(
				DungeonScreenView.getInstance(),
				DungeonScreenView.getInstance().getClass().getMethod(
						"init"), new Object[] {});
		LoadingView.getInstance().setRendered(false);
		// game state goes to load screen
		GameState.getInstance().setCurrentState(
				GameState.STATE_11LOADING);
		startGame();
	}
	/**
	 * Loads the character chooser screen.
	 * @throws Exception if an error occurs
	 */
	public void loadDungeonSplash() throws Exception {
		// load screen should switch to HQ CHAR CHOOSER
		LoadingView.getInstance().setNextState(
				GameState.STATE_15HQ_DUNGEON_SPLASH);
		LoadingView.getInstance().setLoadAction(
				DungeonSplashView.getInstance(),
				DungeonSplashView.getInstance().getClass().getMethod(
						"init"), new Object[] {});
		LoadingView.getInstance().setRendered(false);
		// game state goes to load screen
		GameState.getInstance().setCurrentState(
				GameState.STATE_11LOADING);
		startGame();
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void setCursor(final int c) {
		cursor = c;
	}
	/**
	 * Sets the chosen pc.
	 * @param refid the reference id of the chosen pc
	 */
	@Override
	public void setPc(final int refid) {
		pc = refid;
	}
	/**
	 * Starts the game.
	 * @throws Exception if an error occurs
	 */
	public void startGame() throws Exception {

	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void switchCursor() {
		try {
		SoftwareCursor.getInstance().switchCursor(cursor);
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
		Pixmap pixmap = null;
		int xHotspot = 0, yHotspot = 0;
		switch (cursor) {
		case GlobalConstants.CURSOR_00_DEFAULT:
			pixmap = new Pixmap(
					Gdx.files.internal("data/cursors/cursor_default.png"));
			break;
		case GlobalConstants.CURSOR_03_WAIT:
			pixmap = crsrWait;
			break;
		case GlobalConstants.CURSOR_12_HAND:
			pixmap = crsrHand;
			break;
		case GlobalConstants.CURSOR_20_PAN_NORTHWEST:
			pixmap = crsrNW;
			break;
		case GlobalConstants.CURSOR_21_PAN_NORTH:
			pixmap = crsrN;
			break;
		case GlobalConstants.CURSOR_22_PAN_NORTHEAST:
			pixmap = crsrNE;
			break;
		case GlobalConstants.CURSOR_23_PAN_EAST:
			pixmap = crsrE;
			break;
		case GlobalConstants.CURSOR_24_PAN_SOUTHEAST:
			pixmap = crsrSE;
			break;
		case GlobalConstants.CURSOR_25_PAN_SOUTH:
			pixmap = crsrS;
			break;
		case GlobalConstants.CURSOR_26_PAN_SOUTHWEST:
			pixmap = crsrSW;
			break;
		case GlobalConstants.CURSOR_27_PAN_WEST:
			pixmap = crsrW;
			break;
		case GlobalConstants.CURSOR_28_MOVE:
			pixmap = crsrMove;
			break;
		case GlobalConstants.CURSOR_29_ATTACK:
			pixmap = crsrAttack;
			break;
		default:
			JOGLErrorHandler.getInstance().fatalError(
					new Exception(
							"Invalid cursor type: " + cursor));
			break;
		}
		//Gdx.input.setCursorImage(pixmap, xHotspot, yHotspot);
		//Gdx.input.setCursorImage(null, xHotspot, yHotspot);
		pixmap = null;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void switchScreen() throws Exception {
		if (!initialized) {
			initialize();
		}
		// load views
		switch (GameState.getInstance().getCurrentState()) {
		case GameState.STATE_01STARTMENU:
			Interface.getInstance().setCurrentView(
					GlobalConstants.VIEW_00_INTRO);
			break;
		case GameState.STATE_11LOADING:
			Interface.getInstance().setCurrentView(
					GlobalConstants.VIEW_01_LOADING);
			break;
		case GameState.STATE_14HQ_CHAR_CHOOSER:
			Interface.getInstance().setCurrentView(
					GlobalConstants.VIEW_02_CHARACTER_CHOOSER);
			break;
		case GameState.STATE_15HQ_DUNGEON_SPLASH:
			Interface.getInstance().setCurrentView(
					GlobalConstants.VIEW_03_DUNGEON_SPLASH);
			break;
		case GameState.STATE_16HQ_DUNGEON_SCREEN:
			Interface.getInstance().setCurrentView(
					GlobalConstants.VIEW_04_DUNGEON_SCREEN);
			break;
		default:
			throw new Exception("Illegal game state!! "
					+ GameState.getInstance().getCurrentState());
			/*
			 * case GameState.STATE_13SB_CHAR_CREATOR:
			 * Interface.getInstance().setCurrentView(
			 * GlobalConstants.VIEW_CHAR_CREATOR_SB); break;
			 */
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void update() {
		try {
			switch (GameState.getInstance().getCurrentState()) {
			case GameState.STATE_16HQ_DUNGEON_SCREEN:
				//HQTurn.getInstance().update();
				break;
			default:
				break;
			}
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		}
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void watchUpdated(Watchable data) {
		if (data instanceof GameState) {
			try {
				switchScreen();
			} catch (Exception ex) {
				JOGLErrorHandler.getInstance().fatalError(ex);
			}
		}
	}

}
